package vn.bum.game.api;

import java.lang.reflect.Type;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import vn.bum.game.om.Game;

import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GameDAO {
	final int PAGE_SIZE = 10;
	
	Type listGameType = new TypeToken<List<Game>>(){}.getType();
	
	MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
	Gson gson = new Gson();
	
	public List<Game> list(int page) {
		Object element = syncCache.get("list" + page);
		if (element != null) {
			return gson.fromJson((String)element, listGameType);
		}
		
		List<Game> games = listDb(page);
		if (games != null && games.size() > 0) {
			syncCache.put("list" + page, gson.toJson(games));
		} else {
			syncCache.delete("list" + page);
		}
		
		return games;
	}
	
	public List<Game> list() {
		Object element = syncCache.get("list");
		if (element != null) {
			return gson.fromJson((String)element, listGameType);
		}
		
		List<Game> games = listDb();
		if (games != null && games.size() > 0) {
			syncCache.put("list", gson.toJson(games));
		} else {
			syncCache.delete("list");
		}
		
		return games;
	}
	
	public List<Game> listDb(int page) {
		if (page < 1) {
			page = 1;
		}
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = pm.newQuery("select from " + Game.class.getName() + " order by code asc");
		query.setRange((page - 1) * PAGE_SIZE, page * PAGE_SIZE);
		
		List<Game> games = (List<Game>)query.execute();
		
		return games;
	}
	
	public List<Game> listDb() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = pm.newQuery("select from " + Game.class.getName() + " order by code asc");
		
		List<Game> games = (List<Game>)query.execute();
		
		return games;
	}

	public Game get(long id) {
		if (id > 0) {
			PersistenceManager pm = PMF.get().getPersistenceManager();
			Game game = pm.getObjectById(Game.class, id);
			return game;
		}

		return null;
	}

	public Game get(String code) {
		Object element = syncCache.get("game:-" + code);
		if (element != null) {
			return gson.fromJson((String)element, Game.class);
		}
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = pm.newQuery("select from " + Game.class.getName()
				+ " where code == codeParam " + "parameters String codeParam");

		List<Game> games = (List<Game>) query.execute(code);
		if (games != null && games.size() > 0) {
			Game game = games.get(0);
			syncCache.put("game:-" + code, gson.toJson(game));
			return game;
		}

		return null;
	}

	public void create(String title, 
			String code, 
			String intro, 
			Long catId, 
			String jarUrl, 
			String jadUrl, 
			String content, 
			int fileSize, 
			String imageUrl) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Game game = new Game();
		game.setTitle(title);
		game.setCode(code);
		game.setIntro(intro);
		game.setCatId(catId);
		game.setJarUrl(jarUrl);
		game.setJadUrl(jadUrl);
		game.setContent(new Text(content));
		game.setFileSize(fileSize);
		game.setImageUrl(imageUrl);
		
		try {
			pm.makePersistent(game);
			syncCache.clearAll();
		} finally {
			pm.close();
		}
	}
	
	public void update(long id, 
			String title, 
			String code, 
			String intro, 
			Long catId, 
			String jarUrl, 
			String jadUrl, 
			String content, 
			int fileSize, 
			String imageUrl) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Game game = pm.getObjectById(Game.class, id);
		
		try {
			if (game != null) {
				game.setTitle(title);
				game.setCode(code);
				game.setIntro(intro);
				game.setCatId(catId);
				game.setJarUrl(jarUrl);
				game.setJadUrl(jadUrl);
				game.setContent(new Text(content));
				game.setFileSize(fileSize);
				game.setImageUrl(imageUrl);
				
				pm.makePersistent(game);
				
				syncCache.clearAll();
			}
		} finally {
			pm.close();
		}
	}
}
